package top.kindaries;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;

/**
 * 登录拦截器
 * <p>
 * Author: kindaries
 * Company: shenzhen
 * Date: Created in 2018-10-24 14:46
 * Created by IntelliJ IDEA.
 */
public class ZuulLoginFilter extends ZuulFilter {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    //URL 表达式
    private final PathMatcher pathMatcher = new AntPathMatcher();

    //忽略的参数
    private static Set<String> ingoreurlPatterns = new HashSet<String>() {{
        add("/**/script/**");
        add("/**/html/**");
        add("/**/*.ico");
        add("/**/*.js");
    }};

    //放行的URL
    private static Set<String> passActionSet = new HashSet<String>() {{
        add("/**/register.do");       //注册
        add("/**/retrieve.do");       //找回
        add("/**/login.do");          //登录
        add("/kindcloud-sys/**");
        add("/kindcloud-tasks/**");
    }};

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;    // pre：前置过滤|route：在路由请求时候被调用
    }

    @Override
    public int filterOrder() {
        return 0;           //优先级为0,数字越大,优先级越低
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String url = request.getRequestURI();
        for (String pattern : ingoreurlPatterns) {
            if (pathMatcher.match(pattern, url)) {                  //匹配URL
                return false;
            }
        }
        return true;        //是否执行该过滤器,此处为true,说明需要过滤
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String url = request.getRequestURI();
        logger.info("{} request to {}触发拦截机制......", request.getMethod(), url);
        int code = 200;
        String msg = "";
        for (String pattern : passActionSet) {
            // 匹配URL
            if (pathMatcher.match(pattern, url)) {
                writeResponse(ctx, code, msg);
                return null;
            }
        }
        code = 501;
        msg = "权限不足吖！";
        writeResponse(ctx, code, msg);
        return null;
    }

    /**
     * 写入返回数据
     */
    private void writeResponse(RequestContext ctx, int code, String msg) {
        if (code == 200) {
            ctx.set("logFlag", 1);  //返回日志标志 控制是否需要记录日志
            ctx.set("startTime", System.currentTimeMillis());   // 请求开始时间
            logger.info("通过权限认证");
            return;
        }
        String str = "{\"code\":" + code + ",\"success\":false,\"msg\":\"" + msg + "\"}";
        logger.error(str);
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(code);
        HttpServletResponse servletResponse = ctx.getResponse();
        servletResponse.setContentType("application/json; charset=utf-8");  // 设置编码
        OutputStream outStream = null;
        try {
            outStream = servletResponse.getOutputStream();
            outStream.write(str.getBytes(servletResponse.getCharacterEncoding()));
            outStream.flush();
        } catch (IOException e) {
            logger.error("返回发生异常");
            logger.error(e.getMessage(), e);
        } finally {
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
    }

}